package com.canplay.screen.utils

import java.text.SimpleDateFormat
import java.util.*

/**
 * @Description: 日期时间工具类
 */
object TimeUtils {

    const val PATTERN_SS = "ss"
    const val PATTERN_EE = "EE"
    const val PATTERN_HH_MM = "HH:mm"
    const val PATTERN_YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss"
    const val PATTERN_YYYY_MM_DD = "yyyy-MM-dd"
    const val PATTERN_YYYY_MM_DD_zh = "yyyy年MM月dd日"
    const val PATTERN_MM_DD_ZH = "MM月dd日"
    const val PATTERN_YYYY_M_D_zh = "yyyy年M月d日"

    private val SDF_THREAD_LOCAL = object : ThreadLocal<Map<String, SimpleDateFormat>>() {
        override fun initialValue(): Map<String, SimpleDateFormat> {
            return hashMapOf()
        }
    }

    private fun getDefaultFormat(): SimpleDateFormat {
        return getSafeDateFormat(PATTERN_YYYY_MM_DD_HH_MM_SS)
    }

    fun getSafeDateFormat(pattern: String): SimpleDateFormat {
        val sdfMap: MutableMap<String, SimpleDateFormat> =
            (SDF_THREAD_LOCAL.get() as Map<String, SimpleDateFormat>).toMutableMap()
        var simpleDateFormat = sdfMap[pattern]
        if (simpleDateFormat == null) {
            simpleDateFormat = SimpleDateFormat(pattern, Locale.getDefault())
            sdfMap[pattern] = simpleDateFormat
        }
        return simpleDateFormat
    }

    fun stringToDate(time: String): Date? {
        return stringToDate(time, getDefaultFormat())
    }

    fun stringToDate(time: String, pattern: String): Date? {
        return stringToDate(time, getSafeDateFormat(pattern))
    }

    fun stringToDate(time: String, format: SimpleDateFormat): Date? {
        var date:Date? = null
        try {
            date = format.parse(time)
        }catch (e:Exception){
            e.printStackTrace()
        }
        return  date
    }

    fun dateToString(date: Date?): String {
        return dateToString(date, getDefaultFormat())
    }

    fun dateToString(date: Date?, pattern: String): String {
        return dateToString(date, getSafeDateFormat(pattern))
    }


    private fun dateToString(date: Date?, format: SimpleDateFormat): String {
        if (date == null) {
            return ""
        }
        return format.format(date)
    }

    fun longToString(dateTime: Long): String {
        return dateToString(Date(dateTime))
    }

    fun longToString(dateTime: Long, pattern: String): String {
        return dateToString(Date(dateTime), pattern)
    }

    fun isToday(time: Long): Boolean {
        return isToday(Date(time))
    }


    fun isToday(date: Date): Boolean {
        val pattern = PATTERN_YYYY_MM_DD
        val now = Calendar.getInstance()
        val nowStr = dateToString(now.time, pattern)
        val dateStr = dateToString(date, pattern)
        return nowStr == dateStr
    }

    fun isTomorrow(date: Date): Boolean {
        val pattern = PATTERN_YYYY_MM_DD
        val tomorrow = Calendar.getInstance()
        tomorrow.add(Calendar.DAY_OF_YEAR, 1)
        val nowStr = dateToString(tomorrow.time, pattern)
        val dateStr = dateToString(date, pattern)
        return nowStr == dateStr
    }

    fun isAm(calendar: Calendar = Calendar.getInstance()): Boolean {
        return calendar.get(Calendar.AM_PM) == 0
    }

    fun isYesterday(date: Date): Boolean {
        val pattern = PATTERN_YYYY_MM_DD
        val yesterday = Calendar.getInstance()
        yesterday.add(Calendar.DAY_OF_YEAR, -1)
        val nowStr = dateToString(yesterday.time, pattern)
        val dateStr = dateToString(date, pattern)
        return nowStr == dateStr
    }

    fun formatDate(time: String, currentPattern: String, targetPattern: String): String {
        val date = stringToDate(time = time, pattern = currentPattern)
        return dateToString(date = date, targetPattern)
    }

    fun inDuration(start: String?, end: String?): Boolean {
        return if (start.isNullOrEmpty() || end.isNullOrEmpty()) true else {
            val startDate = stringToDate(start)!!
            val endDate = stringToDate(end)!!
            val current = Date()
            current in startDate..endDate
        }
    }

}

fun Calendar.isToday(): Boolean {
    return TimeUtils.isToday(this.time)
}

fun Calendar.isTomorrow(): Boolean {
    return TimeUtils.isTomorrow(this.time)
}

fun Date.isToday(): Boolean {
    return TimeUtils.isToday(this)
}

fun Date.isTomorrow(): Boolean {
    return TimeUtils.isTomorrow(this)
}